package com.example.gobang.game;

import com.example.gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 负责完成匹配功能
 */
@Component
public class Mather {

    private Queue<User> normalQueue = new LinkedList<>();

    private Queue<User> highQueue = new LinkedList<>();

    private Queue<User> veryHighQueue = new LinkedList<>();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private RoomManager roomManager;
    private ObjectMapper objectMapper;

    /**
     * 将玩家放入匹配队列中
     *
     * @param user
     */
    public void add(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.offer(user);
            }
            System.out.println(user.getUsername() + "进入normalQueue");
        } else if (user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.offer(user);
            }
            System.out.println(user.getUsername() + "进入highQueue");
        } else if (user.getScore() < 5000) {
            synchronized (veryHighQueue) {
                veryHighQueue.offer(user);
            }
            System.out.println(user.getUsername() + "进入veryhighQueue");
        }
    }

    /**
     * 当玩家停止匹配,从匹配队列中删除
     *
     * @param user
     */
    public void remove(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.remove(user);
                normalQueue.notify();
            }
            System.out.println(user.getUsername() + "移除normalQueue");
        } else if (user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.remove(user);
                highQueue.notify();
            }
            System.out.println(user.getUsername() + "移除highQueue");
        } else if (user.getScore() < 5000) {
            synchronized (veryHighQueue) {
                veryHighQueue.remove(user);
                veryHighQueue.notify();
            }
            System.out.println(user.getUsername() + "移除veryhighQueue");
        }
    }

    public Mather() {
        Thread t1 = new Thread() {
            @SneakyThrows
            @Override
            public void run() {
                while (true) {
                    handlerMatch(normalQueue);
                }
            }
        };

        Thread t2 = new Thread() {
            @SneakyThrows
            @Override
            public void run() {
                while (true) {
                    handlerMatch(highQueue);
                }
            }
        };

        Thread t3 = new Thread() {
            @SneakyThrows
            @Override
            public void run() {
                while (true) {
                    handlerMatch(veryHighQueue);
                }
            }
        };
    }

    public void handlerMatch(Queue<User> matchQueue) throws IOException, InterruptedException {
        synchronized (matchQueue) {
            // 玩家数 < 2
            while (matchQueue.size() < 2) {
                matchQueue.wait();
            }
            User player1 = matchQueue.poll();
            User player2 = matchQueue.poll();
            System.out.println("匹配出两个玩家:" + player1.getUsername() + "," + player2.getUsername());

            // 获取玩家的websocket会话
            WebSocketSession session1 = onlineUserManager.getSessionFromGameHall(player1.getUserId());
            WebSocketSession session2 = onlineUserManager.getSessionFromGameHall(player2.getUserId());
            if (session1 == null) {
                // 玩家1不在线,将玩家2放回队列中
                matchQueue.offer(player2);
                return;
            }

            if (session2 == null) {
                // 同理
                matchQueue.offer(player1);
                return;
            }
            // 玩家1和玩家2是同一个
            if (session1 == session2) {
                matchQueue.offer(player1);
                return;
            }


            Room room = new Room();
            roomManager.add(room, player1.getUserId(), player2.getUserId());

            // 给玩家反馈 匹配到对手了
            MatchResponse response1 = new MatchResponse();
            response1.setOk(true);
            response1.setMessage("matchSuccess");
            session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response1)));

            MatchResponse response2 = new MatchResponse();
            response2.setOk(true);
            response2.setMessage("matchSuccess");
            session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));
        }

    }
}
